package javawdw.picture.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javawdw.picture.api.Picture;
import javawdw.picture.util.PictureSpliter;

/**
 * 动态图片类<br>
 * 包括每帧图片，每帧时间等
 * 
 * @author David
 * 
 */
public class DynPicture implements Picture {
	private List<Frame> frames;
	private List<Integer> delayTimes;
	private int minHeight;
	private int minWidth;

	/**
	 * 根据给定的编码解码器构造DynPicture
	 * 
	 * @param pictureCodec
	 *            给定的编码解码器
	 */
	public DynPicture() {
	}

	/**
	 * 获得DynPicture所有帧图片
	 * 
	 * @return 返回得到的图片
	 */
	public List<Frame> getFrames() {
		return Collections.unmodifiableList(this.frames);
	}

	/**
	 * 获得DynPicture所有帧间隔时间
	 * 
	 * @return 返回得到的间隔时间列表
	 */
	public List<Integer> getDelayTimes() {
		return Collections.unmodifiableList(this.delayTimes);
	}

	/**
	 * 获得DynPicture所有帧所有图片的最小高度
	 * 
	 * @return 返回获得的高度
	 */
	public int getHeight() {
		return this.minHeight;
	}

	/**
	 * 获得DynPicture所有帧所有图片的最小宽度
	 * 
	 * @return 返回获得的宽度
	 */
	public int getWidth() {
		return this.minWidth;
	}

	/**
	 * 在当前DynPicture的指定位置画另一张图片
	 * 
	 * @param picture
	 *            要添加的图片
	 * @param position
	 *            添加图片的位置
	 */
	public void draw(Picture picture, Position position) {
		this.draw(picture, position, 1);
	}

	/**
	 * 在当前DynPicture的指定位置画另一张图片
	 * 
	 * @param picture
	 *            要添加的图片
	 * @param position
	 *            添加图片的位置
	 * @param transparency
	 *            透明度(0~1,1为不透明)
	 */
	public void draw(Picture picture, Position position, double transparency) {
		List<Frame> list = PictureSpliter.split(picture);
		int listSize = list.size();
		int i = 0;
		for (Frame p : this.frames) {
			int index = (i < listSize) ? i : i % list.size();
			p.draw(list.get(index), position, transparency);
		}
	}

	/**
	 * 在当前DynPicture的指定位置写字
	 * 
	 * @param content
	 *            要添加文字的内容
	 * @param style
	 *            字体信息
	 * @param position
	 *            要添加文字的位置
	 */
	public void draw(String content, TextStyle style, Position position) {
		this.draw(content, style, position, 1);
	}

	/**
	 * 在当前DynPicture的指定位置写字
	 * 
	 * @param content
	 *            要添加文字的内容
	 * @param style
	 *            字体信息
	 * @param position
	 *            要添加文字的位置
	 * @param transparency
	 *            透明度(0~1,1为不透明)
	 */
	public void draw(String content, TextStyle style, Position position,
			double transparency) {
		for (Picture picture : this.frames) {
			picture.draw(content, style, position, transparency);
		}
	}

	/**
	 * 根据给定横向、纵向比率缩放DynPicture
	 * 
	 * @param ratioX
	 *            给定横向比率
	 * @param ratioY
	 *            给定纵向比率
	 */
	public void zoom(double ratioX, double ratioY) {
		for (Picture picture : this.frames) {
			picture.zoom(ratioX, ratioY);
		}
	}

	/**
	 * 根据开始坐标点、宽、高裁剪DynPicture
	 * 
	 * @param startPosition
	 *            给定的开始坐标点
	 * @param newWidth
	 *            给定的宽度
	 * @param newHeight
	 *            给定的高度
	 */
	public void crop(Position startPosition, int newWidth, int newHeight) {
		for (Picture pictrue : this.frames) {
			pictrue.crop(startPosition, newWidth, newHeight);
		}
	}

	/**
	 * 根据角度和生成图片的宽度、高度以图片中心为原点旋转DynPicture
	 * 
	 * @param degree
	 *            给定的角度
	 * @param newWidth
	 *            给定的宽度
	 * @param newHeight
	 *            给定的高度
	 */
	public void revolve(double degree, int newWidth, int newHeight) {
		for (Picture picture : this.frames) {
			picture.revolve(degree, newWidth, newHeight);
		}
	}

	/**
	 * 复制DynPicture
	 * 
	 * @return 复制得到的DynPicture
	 */
	public DynPicture clone() {
		List<Frame> pics = new ArrayList<Frame>();
		List<Integer> times = new ArrayList<Integer>();
		for (int i = 0; i < this.frames.size(); i++) {
			pics.add(this.frames.get(i).clone());
			times.add(this.delayTimes.get(i));
		}
		DynPicture dynPicture = new DynPicture();
		dynPicture.frames = pics;
		dynPicture.delayTimes = times;
		return dynPicture;
	}

	/**
	 * 将Frame帧转化为DynPicture
	 * 
	 * @param frame
	 *            要转化的Frame帧
	 * @return 返回生成的DynPicture
	 */
	public static DynPicture transfer(Frame frame) {
		DynPicture dynPicture = new DynPicture();
		dynPicture.append(frame, 0);
		return dynPicture;
	}

	/**
	 * 在当前DynPicture的末尾插入帧
	 * 
	 * @param frame
	 *            要插入的图片
	 * @param delayTime
	 *            播放时间
	 */
	public void append(Frame frame, int delayTime) {
		int index = this.frames.size() - 1;
		this.append(index, frame, delayTime);
	}

	/**
	 * 在当前DynPicture的指定帧位置插入帧
	 * 
	 * @param index
	 *            指定帧位置
	 * @param picture
	 *            要插入的图片
	 * @param delayTime
	 *            播放时间
	 */
	public void append(int index, Frame frame, int delayTime) {
		if (delayTime > 0 && frame != null) {
			this.frames.add(index, frame);
			this.delayTimes.add(index, delayTime);
			reset();
		}
	}

	private void reset() {
		for (Picture picture : this.frames) {
			if (minHeight > picture.getHeight()) {
				this.minHeight = picture.getHeight();
			}
		}
		for (Picture picture : this.frames) {
			if (minWidth > picture.getWidth()) {
				this.minWidth = picture.getWidth();
			}
		}
	}
}